﻿//* Copyright(C) 2005-2012, all rights reserved.
//*
//* The following code is copyrighted and contains proprietary information
/* and trade secrets of Foxit Software Inc.      
**************************************************************************
*/

/**
* 单页显示
*/



define(function (require, exports, module) {
    require('../ViewLevel.js');
    var LayoutInfo = require('./LayoutInfo');
    var env = require('../Environment');
    var CommonTools = require('../Common');
    var Config = require("../Config");
    FXREADER.PDFView.CSinglePageViewLayout = function (pDocView, stLayoutInfo) {
        var _pDocView = pDocView;
        var _nCurPageIndex = 0,
             _stLayoutInfo = stLayoutInfo,
             _VisablePageRange = { begin: 0, end: 0, current: 0 },  //处于显示区域的页面;
             _nViewMode = FXREADER.PDFView.RD_BRMODE_CONTINUOUS, //显示模式;
             _self = this;
			 if(FXREADER.Environment.mobile || FXREADER.Environment.iOS)
				_stLayoutInfo.cxMargin = 0;
			 else
				_stLayoutInfo.cxMargin = 15;
        //   _stLayoutInfo.nShowMode = FXREADER.PDFView.RD_BRMODE_CONTINUOUS_FACING;

        var _BlankImg = "";
        var _ScrollKeyDownCallback = { 37: function () {
            _self.GoPrevPage();
        }, 33: function () {
            _self.GoPrevPage();
        }, 39: function () {
            _self.GoNextPage();
        }, 34: function () {
            _self.GoNextPage();
        }, 35: function () {
            _self.GotoPage(_pDocView.GetPageCount() - 1, 0, 0);
        }, 36: function () {
            _self.GotoPage(0, 0, 0);
        }
        };


        _Construct();
        //private methods

        //初始化
        function _Construct() {
        }

        function _CalcLayoutFacingCount() {
            //目前只提供单页
            var nFacingCount = 1;
            var pageCount = _pDocView.GetPageCount();
            if (_stLayoutInfo.bFacing) {
                nFacingCount = (_stLayoutInfo.nFacingCount <= pageCount) ? _stLayoutInfo.nFacingCount : pageCount;
            }
            return nFacingCount;
        }

        function _GetFitPageScale() {
            var mh = _pDocView.GetMaxPageViewHeight();
            var mws = _pDocView.GetMaxPageViewWidth();
            return _GetFitRectScale(mws, mh);
        }

        this.GetFitWidthScale = function(bUseRealScale) {
            var nFacingCount = _CalcLayoutFacingCount();
            var maxPageWidth = 0;
            if(bUseRealScale!=null && bUseRealScale==true)
            {
            	maxPageWidth = _pDocView.GetMaxPageViewWidthNoScale();
            }
            else
            	maxPageWidth = _pDocView.GetMaxPageViewWidth();
            return _CalcFitWidthScale(_stLayoutInfo.cxMargin, maxPageWidth,
		                           _stLayoutInfo.nPageSpace, nFacingCount);
        }
        
        function _CalcFitWidthScale(nMagin_X, nPageWidth, nPageSpace_H, nFacingCount) {
            var a = _pDocView.GetDocViewWidth() - 2 * nMagin_X - nPageSpace_H * (nFacingCount - 1);
            var b = nPageWidth;
            var dbScale = a / b;
			dbScale = Math.round(dbScale*100)/100;
            return dbScale;
        }

        this.GetFitHeightScale = function() {
            var mh = _pDocView.GetMaxPageViewHeight();
            return _CalcFitHeightScale(_stLayoutInfo.cyMargin, mh);
        }

        function _GetFitRectScale(nRcWidth, nRcHeight) {
            var nFacingCount = _CalcLayoutFacingCount();
            return _CalcFitRectangleScale(_stLayoutInfo.cxMargin,
		                               _stLayoutInfo.cyMargin,
		                               nRcWidth, nRcHeight,
									   _stLayoutInfo.nPageSpace,
									   nFacingCount);
        }

        function _CalcLayoutScale(nZoomToMode, dbScale, nFitRcHeight, nFitRcWidth, bCalcScaleFromMode) {
            var new_scale = dbScale;
            switch (nZoomToMode) {
                case FXREADER.PDFView.RD_ZMODE_CUSTOM:
                    new_scale = dbScale;
                    break;
                case FXREADER.PDFView.RD_ZMODE_ACTUAL_SIZE:
                    new_scale = 1.0;
                    break;
                case FXREADER.PDFView.RD_ZMODE_FIT_PAGE:
                    new_scale = _GetFitPageScale();
                    break;
                case FXREADER.PDFView.RD_ZMODE_FIT_WIDTH:
                    new_scale = _self.GetFitWidthScale();
                    break;
                case FXREADER.PDFView.RD_ZMODE_FIT_HEIGHT:
                    new_scale = _self.GetFitHeightScale();
                    break;
                case FXREADER.PDFView.RD_ZMODE_FIT_RECTANGLE:
                    new_scale = (nFitRcWidth <= -1 && nFitRcHeight <= -1) ? dbScale : _GetFitRectScale(nFitRcWidth, nFitRcHeight);
                    break;
                case FXREADER.PDFView.RD_ZMODE_NONE:
                    break;
                default:
                    break;
            }

            new_scale = _GetLayoutAdjustScale(new_scale);
            if (new_scale == 0 || new_scale == "NaN")
                new_scale = dbScale;
            return new_scale;
        }

        function _GetLayoutAdjustScale(dbScale) {
            var dbScale = parseInt((dbScale + 0.2) / 0.5) * 0.5;

            if (dbScale < (_stLayoutInfo.dbMinScale))
                return _stLayoutInfo.dbMinScale;
            if (dbScale > _stLayoutInfo.dbMaxScale)
                return _stLayoutInfo.dbMaxScale;
            return dbScale;
        }


        //[计算按给定大小来显示时的显示倍数]
        function _CalcFitRectangleScale(nMagin_X, nMargin_Y, nRcWidth, nRcHeight,
											 nPageSpace_H, nFacingCount) {

            //[计算按横向大小来显示时的显示倍数]	;
            var a1 = _pDocView.GetDocViewWidth() - 2 * nMagin_X - nPageSpace_H * (nFacingCount - 1);
            var b1 = nRcWidth;
            var dbScale1 = a1 / b1;

            //[计算竖按向大小来显示时的显示倍数];

            var a2 = _pDocView.GetDocViewHeight() - 2 * nMargin_Y;
            var b2 = nRcHeight;
            var dbScale2 = a2 / b2;
            //[拿一个最小的倍数来计算];
            var dbScale3 = (dbScale1 < dbScale2) ? dbScale1 : dbScale2;
            return dbScale3;
        }

        function _SetLayoutZoomToMode(iZoomMode) {
            _stLayoutInfo.iZoomMode = iZoomMode;
        }

        function _UpdatePreview(scale) {
            _stLayoutInfo.dbScale = scale;
            _pDocView.OnZoom(_stLayoutInfo.dbScale);
        }

        //public methods
        //创建包含所有页面的div层;
        this.CreateDocViewHtml = function () {
            var html = "";
            switch (_stLayoutInfo.nShowMode) {
                case FXREADER.PDFView.RD_BRMODE_CONTINUOUS:
                    {
                        html = "<div id='" + _pDocView.GetDocViewContainerID() + "' class='fwr_pages scroll-pane' style='position:relative;width:"
                            + _pDocView.GetDocViewWidth() + "px;height:" + _pDocView.GetDocViewHeight() + "px; overflow-y: auto;overflow-x: auto;"
                            + "'></div>";
                    }
                    break;
                case FXREADER.PDFView.RD_BRMODE_CONTINUOUS_FACING:
                    {
                        html = "<div id='" + _pDocView.GetDocViewContainerID() + "' style='height:100%;" + "' class='scroll-pane'>" +
                            "<div id='" + _pDocView.GetLeftDocContainerID() + "' class='' style='position:relative;top:0px;overflow:hidden;padding-top: 14px;float:left'></div><div id='" +
                            _pDocView.GetRightDocContainerID() + "' class='' style='margin-left:10px;position:relative;top:0px;overflow:hidden;padding-top: 14px;float:left'></div></div>";
                    }
                    break;
                default:
            }
            return html;
        }



        //创建页面的div层;
        this.CreatePageViewHtml = function (iPageIndex) {
            var pPageView = _pDocView.GetPageView(iPageIndex);
            if (pPageView == null)
                return "";
            var pPageViewRender = _pDocView.GetPageViewRender();
            var nPageViewWidth = pPageView.GetPDFPageWidth() * _self.GetScale() * pPageViewRender.GetPixelsPerPoint();
            var nPageViewHeight = pPageView.GetPDFPageHeight() * _self.GetScale() * pPageViewRender.GetPixelsPerPoint();
            pPageView.SetPageViewWidth(nPageViewWidth);
            pPageView.SetPageViewHeight(nPageViewHeight);
            var nLeftMargin = (_pDocView.GetDocViewWidth() - nPageViewWidth) / 2;
            var dimensions = "height:" + nPageViewHeight + "px;width:" + nPageViewWidth + "px;margin-left:" + nLeftMargin + "px;";
            var pageImgClass = env.gecko ? "border  fwr_hidden fwr_page_bg_image" : "border  fwr_hidden fwr_page_bg_image";
            var loadingGif = "./images/loading.gif";
            var html = "";
            switch (_stLayoutInfo.nShowMode) {
                case FXREADER.PDFView.RD_BRMODE_CONTINUOUS:
                    {
                        html = "<div class='fwr_page' id='" + pPageView.GetPageContainerID() + "' style='position:relative;" + dimensions + "'><div id='"
                            + pPageView.GetWrapPageID() + "' class='fwr_page border ' style='width:100%;height:100%' ></div><img alt='' src='" + _BlankImg
                            + "' id='" + pPageView.GetPageBGImgID() + "' class='" + pageImgClass + "' style='width:100%;height:100%;background-size:cover' />"
                            + "<img id='" + pPageView.GetPageLoaderImgID() + "' src='" + loadingGif + "' style='position:absolute;left:50%;top:50%;margin-top:-12px;margin-left:-12px' />"
                        html += "</div>";
                    }
                    break;
                case FXREADER.PDFView.RD_BRMODE_CONTINUOUS_FACING:
                    {
                        html = "<div class='fwr_page' id='" + pPageView.GetPageContainerID() + "' style='position:relative;" + dimensions + "'><div id='"
                            + pPageView.GetWrapPageID() + "' class='fwr_page border ' style='width:100%;height:100%' ></div><img alt='' src='" + _BlankImg
                            + "' id='" + pPageView.GetPageBGImgID() + "' class='" + pageImgClass + "' style='width:100%;height:100%;background-size:cover' />"
                            + "<img id='" + pPageView.GetPageLoaderImgID() + "' src='" + loadingGif + "' style='position:absolute;left:50%;top:50%;margin-top:-12px;margin-left:-12px' />"
                        html += "</div>";
                    }
                    break;
                default:
            }


            return html;
        }


        //创建页面区间中页面的div，并添加到dom;
        this.CreatePagesView = function (nStartIndex, nEndIndex, nInsertAfterPageIndex) {
            var fragment = document.createDocumentFragment();
            for (var i = nStartIndex; i <= nEndIndex; i++) {
                var pageHtml = _self.CreatePageViewHtml(i);
                var elem = document.createElement("div"); //ie8必须要有这层div，比较奇怪，如果不存在，有时候页面样式应用不成功
                elem.innerHTML = pageHtml;
                fragment.appendChild(elem);
                _pDocView.GetPageView(i).SetContentCreatedState(true);
            }

            var insertPageID = _pDocView.GetPageViewContainerID(nInsertAfterPageIndex);
            var oElement = null;

            if (nInsertAfterPageIndex == -1)
                oElement = $("#" + _pDocView.GetDocViewContainerID())[0].appendChild(fragment);
            else {
                oElement = CommonTools.insertAfter(fragment, document.getElementById(insertPageID).parentNode);
            }

            return true;

        }



        //初始化滚动条
        this.InitalizeScrollbar = function () {
            var pPageViewRender = _pDocView.GetPageViewRender();
            _pDocView.InitializeScrollbar({ showArrows: false, animateScroll: false, contentWidth: (pPageViewRender.GetPixelsPerPoint() * _pDocView.GetMaxPDFPageWidth() * _self.GetScale() + 0.5),
                keyDownCallback: _ScrollKeyDownCallback
            });
        }

        this.ReInitializeScrollBar = function () {
            var pPageViewRender = _pDocView.GetPageViewRender();
            _pDocView.ReInitializeScrollBar({ showArrows: false, animateScroll: false, contentWidth: (pPageViewRender.GetPixelsPerPoint() * _pDocView.GetMaxPDFPageWidth() * _self.GetScale() + 0.5),
                keyDownCallback: _ScrollKeyDownCallback
            });
        };

        this.GetVisablePageRange = function () {
            return _VisablePageRange;
        };

        /**
        *步进式修改页面状态.
        * @param [nPageIndex] 步进式处理后，要跳转到的页面索引
        * @param [nStartPage] 要修改状态的页面起始索引
        * @param [nEndPage] 要修改状态的页面结束索引
        * @param [nOffsetY] 第一个参数指定页面相对于当前显示区域的y轴偏移量
        * @param [bScrollX] 是否滚动X轴
        * @param [bResizeScroll] 是否重新计算滚动条
        */
        this.ProgressiveUpdateState = function (nPageIndex, nStartPage, nEndPage, nOffsetY, bScrollX, bResizeScroll) {
            var nSVisableIndex = 0, nEVisableIndex = 0;
            var bChange = false;
            var nd = Config.maxResizePagesPerTime;
            if (nd == -1) //为-1代表所有页面
                nd = _pDocView.GetPageCount();
            nSVisableIndex = nStartPage - nd > 0 ? nStartPage - nd : 0;
            nEVisableIndex = nEndPage + nd;
            if (nEVisableIndex >= _pDocView.GetPageCount())
                nEVisableIndex = _pDocView.GetPageCount() - 1;
            var nRelationPage = 0;
            var viewerContainerWidth = pDocView.GetDocViewWidth();
            for (var i = nSVisableIndex; i <= nEVisableIndex; i++) {
                var pPageView = _pDocView.GetPageView(i);
                if (!pPageView.IsContentCreated())
                    continue;
                if (!pPageView.IsScaleUpdated()) {
                    bChange = true;
                }
                else
                    continue;
                pPageView.UpdateDimension(), pPageView.SetScaleUpdated(true);
                pPageView.SetScale(_self.GetScale());
            }

            if (bChange && bResizeScroll) {
                var ScrollApi = _pDocView.GetScrollApi();
                if (ScrollApi != null) {
                    _self.ReInitializeScrollBar();
                    var offsetX = ScrollApi.getContentPositionX();
                    var pPageView = _pDocView.GetPageView(nPageIndex);
                    ScrollApi.scrollToElement("#" + pPageView.GetPageContainerID(), true, false, nOffsetY);
                    bScrollX && ScrollApi.scrollToX(offsetX);
                }
                else {
                    _pDocView.InitializeScrollbar({ showArrows: false, animateScroll: false
                        , contentWidth: (pPageViewRender.GetPixelsPerPoint() * _nMaxPDFPageWidth * _self.GetScale() + 0.5), keyDownCallback: _ScrollKeyDownCallback
                    });
                }
                return true;
            }
            else {
                return false;
            }
        }

        //获取页面相对于视口区域的偏移
        this.GetPageOffsetDocY = function (iPageIndex) {
            var pPageView = _pDocView.GetPageView(iPageIndex);
            if (!pPageView.IsContentCreated())
                return 0;
            var pageOffset = $("#" + pPageView.GetPageContainerID()).offset();
            var docViewOffset = $("#" + _pDocView.GetDocViewContainerID()).offset();
            return docViewOffset.top - pageOffset.top;
        }

        //跳转到下一页
        this.GoNextPage = function () {
            var iCurPageIndex = _pDocView.GetCurPageIndex();
            if (iCurPageIndex >= _pDocView.GetPageCount())
                return;
            _pDocView.GotoPage(iCurPageIndex + 1);
        }
        //跳转到上一页
        this.GoPrevPage = function () {
            var iCurPageIndex = _pDocView.GetCurPageIndex();
            if (iCurPageIndex <= 0)
                return;
            _pDocView.GotoPage(iCurPageIndex - 1);
        }

        /**
        * 跳转到对应页面.
        * @param [iPageIndex] 页面索引
        * @param [OffsetX] 相对要跳转页面的左边距离
        * @param [OffsetY] 相对要跳转页面的顶部距离
        */
        this.GotoPage = function (iPageIndex, OffsetX, OffsetY) {
            _pDocView.GotoPage(iPageIndex, OffsetX, OffsetY);
        }

        this.GotoPageByDest = function (destinfo) {
            if (destinfo == null || destinfo.iPage < 0 || destinfo.iPage >= _pDocView.GetPageCount())
                return;
            var pPageViewRender = _pDocView.GetPageViewRender();
            var nPt2Pixel = pPageViewRender.GetPixelsPerPoint();

            _self.ZoomtoPage(destinfo.nZoomToMode, destinfo.dbScale, destinfo.width * nPt2Pixel, destinfo.height * nPt2Pixel, true);

            var destTop = 0;
            var destLeft = 0;
            if (destinfo.top != -1) {
                var top = destinfo.top; //_Render.GetPDFPageHeight(_destInfo.iPage) - _destInfo.top;
                destTop = top * _stLayoutInfo.dbScale * nPt2Pixel;
            }
            if (destinfo.left != -1) {
                var left = destinfo.left;
                destLeft = left * _stLayoutInfo.dbScale * nPt2Pixel;
            }
            _self.GotoPage(destinfo.iPage, destLeft, destTop);
        }


        this.ZoomtoPage = function (iZoomMode, dbScale, iFitW, iFitH, bCalcScaleFromMode) {
            if (iZoomMode <= FXREADER.PDFView.RD_ZMODE_CUSTOM || iZoomMode > FXREADER.PDFView.RD_ZMODE_FIT_VISIBLE)
                return;
            if (iZoomMode == 1)
                dbScale = _GetLayoutAdjustScale(dbScale);
            //[改变缩放模式]
            _SetLayoutZoomToMode(iZoomMode);
            //[计算真正要缩放例]
            var new_scale = _CalcLayoutScale(iZoomMode, dbScale, iFitW, iFitH, bCalcScaleFromMode);
            //[由比例更新Preview]

            _UpdatePreview(new_scale);
        }


        //获取放大倍数
        this.GetScale = function () { return _stLayoutInfo.dbScale; }
        //设置放大倍数
        this.SetScale = function (dbScale) { _stLayoutInfo.dbScale = dbScale; }


        this.GetDisplayPageRange = function () {
            return _VisablePageRange;
        }

        //获取处于当前显示区域的页面范围
        this.CountDisplayPageRange = function () {
            var range = {};
            range.begin = 0;
            range.end = 1;
            range.current = 0;
            var pagenums = _pDocView.GetCreatedPageNums();
            var initedPageCnt = pagenums.length;
            var left = 0;
            var right = initedPageCnt - 1;
            var mid = (left + right) >> 1;
            var jqPagesContainerDiv = $("#" + _pDocView.GetDocViewContainerID());

            var contentPaneHeight = jqPagesContainerDiv.height(); // $('#mainContainer').height();
            var contentPanelWidth = jqPagesContainerDiv.width();
            var contentPanelOffset = jqPagesContainerDiv.offset();


            var conpos = jqPagesContainerDiv.position();
            while (mid > left) {
                var pPageView = _pDocView.GetPageView(pagenums[mid]);
                var jqPage = $("#" + pPageView.GetPageContainerID());
                var pos = jqPage.offset();
                var height = pPageView.GetPageViewHeight();
                var width = pPageView.GetPageViewWidth();
                var page_top = pos.top;
                if ((page_top <= contentPanelOffset.top) && (page_top + height <= contentPanelOffset.top)) {
                    left = mid + 1;
                    mid = (left + right) >> 1;
                } else if ((page_top > (contentPanelOffset.top + contentPaneHeight))) {
                    right = mid - 1;
                    mid = (left + right) >> 1;
                } else {
                    break;
                }
            }

            range.begin = pagenums[mid];
            range.end = range.begin; // +1;

            for (var i = mid; i >= 0; i--) {
                var pPageView = _pDocView.GetPageView(pagenums[i]);
                var jqPage = $("#" + pPageView.GetPageContainerID());
                var pos = jqPage.offset();
                var height = pPageView.GetPageViewHeight();
                var width = pPageView.GetPageViewWidth();
                var page_top = pos.top;
                if (page_top + height > contentPanelOffset.top) {
                    range.begin = pagenums[i];
                } else {
                    if (i == mid && mid < initedPageCnt - 1) {  //mid页面不可见
                        mid += 1;
                        range.begin = pagenums[mid];
                    }
                    break;
                }
            }

            range.current = range.begin;
            range.end = pagenums[mid]; // range.begin;
            for (var i = mid + 1; i < initedPageCnt; i++) {
                var pPageView = _pDocView.GetPageView(pagenums[i]);
                var jqPage = $("#" + pPageView.GetPageContainerID());
                var pos = jqPage.offset();
                var height = pPageView.GetPageViewHeight();
                var width = pPageView.GetPageViewWidth();
                var page_top = pos.top;
                if (page_top < contentPaneHeight + contentPanelOffset.top) {
                    range.end = pagenums[i]; // +1;
                } else {
                    break;
                }
            }

            for (var i = range.begin; i <= range.end; i++) {
                var pPageView = _pDocView.GetPageView(i);
                if (!pPageView.IsContentCreated()) {
                    range.begin = i + 1;
                    continue;
                }
            }


            for (var i = range.begin; i <= range.end; i++) {
                var pPageView = _pDocView.GetPageView(i);
                if (!pPageView.IsContentCreated())
                    continue;
                var jqPage = $("#" + pPageView.GetPageContainerID());
                var height = pPageView.GetPageViewHeight();
                var width = pPageView.GetPageViewWidth();
                var pos = jqPage.offset();
                var page_top = pos.top;
                if (((page_top >= contentPanelOffset.top) && (page_top < contentPanelOffset.top + contentPaneHeight)
                                                    && (page_top + height / 3 <= contentPanelOffset.top + contentPaneHeight))
                                                || ((page_top <= contentPanelOffset.top) && (page_top + height >= contentPanelOffset.top + contentPaneHeight * 2 / 3))) {
                    range.current = i;
                    break;
                }
                else {
                    continue;
                }

            }

            _VisablePageRange = range;
            return range;
        }

    }

    return FXREADER.PDFView.CSinglePageViewLayout;
});